/*!
\copyright  Copyright (c) 2025 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file
\ingroup    media_processing
\brief      Delayed application of EQ preset and gain selection for the purpose of peer synchronization

*/

#if defined(INCLUDE_MUSIC_PROCESSING)

#include "music_processing_delayed.h"

#include <user_eq.h>

#include <logging.h>
#include <panic.h>

#include <stdlib.h>

typedef enum
{
    MUSIC_PROCESSING_INTERNAL_SELECT_EQ_BANK,
    MUSIC_PROCESSING_INTERNAL_SET_USER_EQ_BANDS,
} music_processing_internal_msg_id_t;

/*! \brief The MUSIC_PROCESSING_INTERNAL_SELECT_EQ_BANK message content. */
typedef struct
{
    /*! Preset ID for the new user EQ */
    uint8 preset;
} MUSIC_PROCESSING_INTERNAL_SELECT_EQ_BANK_T;

/*! \brief The MUSIC_PROCESSING_INTERNAL_SET_USER_EQ_BANDS message content. */
typedef struct
{
    /*! Start band of gain changes */
    uint8 start_band;
    /*! End band of gain hanges */
    uint8 end_band;
    /*! Gains list for the bands */
    int16 *gain;
} MUSIC_PROCESSING_INTERNAL_SET_USER_EQ_BANDS_T;

static void MusicProcessing_MessageHandler(Task task, MessageId id, Message message);
static TaskData task_data = {.handler = MusicProcessing_MessageHandler};

bool MusicProcessing_SetPresetWithDelay(uint8 bank, uint32 delay_ms)
{
    if(!UserEq_IsPresent())
    {
        DEBUG_LOG_ERROR("MusicProcessing_SetPresetWithDelay Error:Music Processing Not Present");
        return FALSE;
    }

    if(!UserEq_IsActive())
    {
        DEBUG_LOG_ERROR("MusicProcessing_SetPresetWithDelay Error:User EQ is NOT active. There is no running audio graph that contains the User EQ.");
        return FALSE;
    }

    MUSIC_PROCESSING_INTERNAL_SELECT_EQ_BANK_T *message = PanicUnlessMalloc(sizeof(MUSIC_PROCESSING_INTERNAL_SELECT_EQ_BANK_T));

    message->preset = bank;

    MessageSendLater((Task)&task_data, MUSIC_PROCESSING_INTERNAL_SELECT_EQ_BANK, message, delay_ms);

    return TRUE;
}

bool MusicProcessing_SetUserEqBandsWithDelay(uint8 start_band, uint8 end_band, int16 * gains, uint32 delay_ms)
{
    MUSIC_PROCESSING_INTERNAL_SET_USER_EQ_BANDS_T *message = PanicUnlessMalloc(sizeof(MUSIC_PROCESSING_INTERNAL_SET_USER_EQ_BANDS_T));

    DEBUG_LOG_VERBOSE("MusicProcessing_SetUserEqBandsWithDelay start band %d, end band %d, first gain %d",
                start_band, end_band, gains[0]);

    size_t size_of_gains = (end_band-start_band+1)*sizeof(int16);

    message->start_band = start_band;
    message->end_band = end_band;
    message->gain = PanicUnlessMalloc(size_of_gains);
    memcpy(message->gain, gains, size_of_gains);

    MessageSendLater((Task)&task_data, MUSIC_PROCESSING_INTERNAL_SET_USER_EQ_BANDS, message, delay_ms);

    return TRUE;
}

static void MusicProcessing_MessageHandler(Task task, MessageId id, Message message)
{
    UNUSED(task);

    switch(id)
    {
        case MUSIC_PROCESSING_INTERNAL_SELECT_EQ_BANK:
        {
            DEBUG_LOG_VERBOSE("UserEqAdaptation_MessageHandler INTERNAL_SELECT_EQ_BANK");
            MUSIC_PROCESSING_INTERNAL_SELECT_EQ_BANK_T *msg = (MUSIC_PROCESSING_INTERNAL_SELECT_EQ_BANK_T *)message;
            UserEq_SelectPreset(msg->preset);
        }
        break;

        case MUSIC_PROCESSING_INTERNAL_SET_USER_EQ_BANDS:
        {
            DEBUG_LOG_VERBOSE("UserEqAdaptation_MessageHandler INTERNAL_SET_USER_EQ_BANDS");
            MUSIC_PROCESSING_INTERNAL_SET_USER_EQ_BANDS_T *msg = (MUSIC_PROCESSING_INTERNAL_SET_USER_EQ_BANDS_T *)message;
            UserEq_SetUserEqGains(msg->start_band, msg->end_band, msg->gain);
            free(msg->gain);

        }
        break;

        default:
        break;
    }
}

#endif